package com.yonyou.gmmc.service.points.eventhandle;

import org.marketing.common.dto.EventDataDTO;
import org.marketing.common.event.BizEvent;
import org.marketing.common.event.EventPointsToPayDTO;
import org.marketing.common.event.enums.EventConstant;
import org.marketing.common.event.enums.EventConstant.EventBizStep;
import org.marketing.common.event.enums.EventConstant.EventBizType;
import org.marketing.common.util.MapConverUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yonyou.gmmc.service.points.exception.PointsException;
import com.yonyou.gmmc.service.points.service.PointsPayService;
import com.yonyou.gmmc.service.points.util.SpringUtil;

/**
 * DCMS用户商城下单事件处理
 * @author Administrator
 *
 */
public class PointsToPayEventHandler extends AbstractEventHandle {

	private static Logger logger = LoggerFactory.getLogger(PointsToPayEventHandler.class);

	// 商城订单
	private static EventBizType BizType = EventConstant.EventBizType.COMMON;
	// 用户下单
	private static EventBizStep BizStep = EventConstant.EventBizStep.COMMON_POINTS_DEDUCT;
	// 用户下单
	private static EventBizStep BizStepReturn = EventConstant.EventBizStep.COMMON_POINTS_RETURN;
	
	//返回积分原因
	private String retrunInfo="积分线下消费返还，";

	// @Autowired
	// private PointsRuleService pointsRuleService;

	@Override
	protected String getHandleInfo() {
		return "积分线下消费，";
	}
	
	

	
	/**
	 * 主要进行数据转换
	 */
	@Override
	protected EventPointsToPayDTO preTransform(BizEvent event) {
		EventPointsToPayDTO o = new EventPointsToPayDTO();
		try {
			o = (EventPointsToPayDTO) MapConverUtil.map2POStrict(event.getEventData(), o);
			logger.info(o.toString());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			this.backInfo = "eventData中的业务数据不能识别：" + e.getMessage();
			throw new PointsException(PointsException.EVENT_CONVERT_FAILD,"eventData中的业务数据不能识别");
		}
		return o;
	}

	/**
	 * 积分处理的逻辑
	 */
	@Override
	protected boolean pay(EventDataDTO eventData) throws PointsException{
		
		boolean isPay=false;//是否扣除了积分
		
		//获取到业务数据
		EventPointsToPayDTO thisEventData = (EventPointsToPayDTO)eventData;
		
		if(thisEventData.getPointsNum()!=null){
			
			PointsPayService pointsPayService = (PointsPayService)SpringUtil.getBean("pointsPayService");;
			Long points = thisEventData.getPointsNum(); 
			
			//1.处理积分的事情
			try {
				//执行积分变动
				if(points>0){
					logger.info("执行积分扣减事件");
					String reasonInfo=this.getHandleInfo()+thisEventData.getDealerName();
					pointsPayService.payPointsToUser(-points, thisEventData.getUserId(),thisEventData.getPhone(),reasonInfo,thisEventData.getWorkOrderNo(),BizStep.getCode(),thisEventData.getPhone());
				}else{
					logger.info("执行积分返还事件");
					String reasonInfo=retrunInfo+thisEventData.getDealerName();
					pointsPayService.payPointsToUser(-points, thisEventData.getUserId(),thisEventData.getPhone(),reasonInfo,thisEventData.getWorkOrderNo(),BizStepReturn.getCode(),thisEventData.getPhone());
				}
				isPay=true;
				
			} catch (Exception e) {
				logger.warn("执行积分扣减操作失败，将向mq发送积分扣减失败事件",e);
				try {
					this.backInfo=e.getMessage();
					isPay=false;
				} catch (Exception e1) {
					this.backInfo="积分变动事件调用MQ失败，需要与MQ状态一致，抛出异常，积分扣减不正常，但事务将回滚";
					logger.error("积分变动事件发送失败",e);
					throw new PointsException(9001,"积分变动事件发送失败");
				}
				
			}
			
			//记录订单状态变更日志
			//int i = pointsPayService.updateOrderStatusLog(isPay,thisEventData.getShoppingOrderNo());
			//logger.info("更新数:"+i);
			
			//2.向MQ发送积分异动的情况
			/*try {
				EventPointsDTO event = new EventPointsDTO(thisEventData.getUserId().toString(),thisEventData.getWorkOrderNo(),points,isPay,"failReason");
				if(points>0){
					BizEvent biz = new BizEvent("",EventBizType.COMMON,EventBizStep.COMMON_POINTS_DEDUCT,MapConverUtil.PO2Map(event));
					pointsPayService.sendEvent2MQ(biz);
				}else{
					BizEvent biz = new BizEvent("",EventBizType.COMMON,EventBizStep.COMMON_POINTS_RETURN,MapConverUtil.PO2Map(event));
					pointsPayService.sendEvent2MQ(biz);
				}
			} catch (Exception e) {
				this.backInfo="积分变动事件调用MQ失败，需要与MQ状态一致，抛出异常，积分扣减正常，但事务将回滚";
				logger.error("积分变动事件发送失败",e);
				throw new PointsException(9001,"积分变动事件发送失败");
			}*/
			
		}else{
			
			this.backInfo = "未找到对应的扣减积分：";
			throw new PointsException(PointsException.RULE_NOTFOUND,"未找到对应的积分");
		}
		return false;
	}


}
